//
//  RxURLSessionViewController.swift
//  DemoProject
//
//  Created by Hao on 2018/8/27.
//  Copyright © 2018年 hao. All rights reserved.
//

import UIKit

fileprivate struct DouBanInfoModel : JSONProtocol {
    
    var abbr_en: String?
    var channel_id: Int?
    var name: String?
    var name_en: String?
    
}

class RxURLSessionViewController: BaseViewController {

    let disposeBag = DisposeBag()
    
    lazy var textView: UITextView = {
        let _tv = UITextView()
        self.view.addSubview(_tv)
        _tv.snp.makeConstraints({ (make) in
            make.left.right.bottom.equalTo(0)
            make.top.equalTo(kStatusBarAndNaviHeight())
        })
        _tv.isEditable = false
        return _tv
    }()
    
    var tableView : UITableView!
    
    let stopButton = UIBarButtonItem()
    let urlString = "https://www.douban.com/j/app/radio/channels" // channels
    
    fileprivate var infoArr = [DouBanInfoModel]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView = UITableView(frame: self.view.bounds, style: .plain)
        self.view.addSubview(tableView)
        tableView.top = kStatusBarAndNaviHeight()
        tableView.height = self.view.height-tableView.top
//        _test1()
//        _testRxAlamofire()
        _testRxAlamofireJson()
        stopButton.title = "停止请求"
        self.navigationItem.rightBarButtonItem = stopButton
    }
    
    private func _test1() {
        guard let url = URL(string:urlString) else { return }
        let request = URLRequest(url: url)
        /// rx.data 与 rx.response 的区别：
        /// 如果不需要获取底层的 response，只需知道请求是否成功，以及成功时返回的结果，那么建议使用 rx.data。
        /// 因为 rx.data 会自动对响应状态码进行判断，只有成功的响应（状态码为 200~300）才会进入到 onNext 回调，否则进入 onError 回调
        
        // 将请求的数据绑定到textview上显示
        URLSession.shared.rx.response(request: request)
            .takeUntil(stopButton.rx.tap)
            .map { (response, data) in
                String(data: data, encoding: String.Encoding.utf8)
            }
            .bind(to: textView.rx.text).disposed(by: disposeBag)
        
//        URLSession.shared.rx.response(request: request).subscribe(onNext: { (response, data) in
//            print(info: "response -> \(response)")
//            let str = String(data: data, encoding: String.Encoding.utf8)
//            print(info: "返回的数据是：\(str ?? "")")
//        }).disposed(by: disposeBag)
        
        // 使用rx.data显示
        URLSession.shared.rx.data(request: request).subscribe(onNext: { (data) in
            print(info: "请求成功！返回的数据是：")
        }, onError: { (error) in
            print(info: "请求失败！错误原因: \(error)")
        }).disposed(by: disposeBag)
        
        
    }

}

extension RxURLSessionViewController {
    
    fileprivate func _testRxAlamofire() {
//        RxAlamofire.request(.get, urlString).data().subscribe(onNext: { data in
//            print(info: "data -> \(data)")
//        }).disposed(by: disposeBag)
        
        // 绑定到textview
//        RxAlamofire.request(.get, urlString).data().map { data in
//            String(data: data, encoding: String.Encoding.utf8)
//        }.bind(to: textView.rx.text).disposed(by: disposeBag)
        
        RxAlamofire.request(.get, urlString).responseData().map { (response, data) -> String in
            // 判断响应结果状态码
            if 200 ..< 300 ~= response.statusCode {
                return String(data: data, encoding: String.Encoding.utf8) ?? ""
            } else {
                return "请求失败"
            }
        }.bind(to: textView.rx.text).disposed(by: disposeBag)
    }
    
    fileprivate func _testRxAlamofireJson() {
        // 返回的数据解析成JSON
//        RxAlamofire.request(.get, urlString).json().subscribe(onNext: { (data) in
//            print(info: "data -> \(data)")
//        }, onError: { (error) in
//            print(info: "error -> \(error)")
//        }).disposed(by: disposeBag)
        
        /// 将请求的数据解析成模型数组在列表中展示
        RxAlamofire.request(.get, urlString).json().map { [weak self] (data) -> [DouBanInfoModel?] in
            let dict = data as? Dictionary<String, Array<[String : Any]>>
            /// 字典数组 转为 模型数组
            if let array = JSONDeserializer<DouBanInfoModel>.deserializeModelArrayFrom(array: dict?["channels"]) {
                return array
//                array.forEach({ (model) in
//                    guard let model = model else { return }
//                    self?.infoArr.append(model)
//                })
            }
            print(info: "-----------------> 字典数组 转为 模型数组失败")
            return self!.infoArr
            /// 一个一个的遍历字典转化为模型
//            if let channels = dict?["channels"] {
//                channels.forEach({ (channel) in
//                    if let model = DouBanInfoModel.deserialize(from: channel) {
//                        self?.infoArr.append(model)
//                    }
//                })
//            }
//            return self!.infoArr
        }.bind(to: tableView.rx.items) { (tableView, row, model) -> UITableViewCell in
            var cell = tableView.dequeueReusableCell(withIdentifier: "RxURLSessionCell")
            if cell == nil {
                cell = UITableViewCell(style: .default, reuseIdentifier: "RxURLSessionCell")
            }
            cell?.textLabel?.text = model?.name
            return cell!
        }.disposed(by: disposeBag)
    }
    
}

